package model;

import java.util.ArrayList;
import java.util.List;

/**
 * 
 * Este algoritmo asigna a los trabajos, los revisores que mas areas en comun tengan con el mismo
 *
 */

public class AlgoritmoUnAreaEnComun extends AlgoritmoDeAsignacion{

	private List<Usuario> revisores = null;
	private List<Trabajo> trabajos = null;

	/**
	 * @param cfp - recibe el CFP en el que debe realizar la asignacion de revisores.
	 * @param sistema - recibe el sistema para poder interactuar de manera magica con el.
	 * @return retorna la lista de revisores del CFP.
	 */
	
	public List<Usuario> ejecutate(CFP cfp, SistemaWeb sistema) {

		this.revisores = cfp.getListaDeRevisores();
		this.trabajos = cfp.getTrabajos();

		for (Trabajo trabajo : this.trabajos) {

			List<Usuario> estosSabenDeEsteTrabajo = this
					.obtenerListaDeRevisoresQueSabenSobreEsteTrabajo(trabajo
							.getAreasInteres());

			this.asignarRevisoresATrabajo(trabajo, estosSabenDeEsteTrabajo);

			for (Usuario usuario : estosSabenDeEsteTrabajo) {
				sistema.enviarMail(usuario, trabajo);
			}

		}
		return revisores;

	}

	private List<Usuario> obtenerListaDeRevisoresQueSabenSobreEsteTrabajo(
			List<String> listaDeAreasDelTrabajo) {

		List<Usuario> losQueSabenDeEsteTrabajo = new ArrayList<Usuario>();

		for (Usuario rev : this.revisores) {

			List<String> areasQueConoceElRevisor = rev.getAreasDeExperiencia();

			for (String area : listaDeAreasDelTrabajo) {

				if (areasQueConoceElRevisor.contains(area)) {

					losQueSabenDeEsteTrabajo.add(rev);

					break;
				}

			}

		}

		if (!(losQueSabenDeEsteTrabajo.size() >= 3)) {

			losQueSabenDeEsteTrabajo = this
					.agregarLosQueFaltan(losQueSabenDeEsteTrabajo);
		}

		return losQueSabenDeEsteTrabajo;

	}

	private void asignarRevisoresATrabajo(Trabajo trabajo,
			List<Usuario> estosSonLosQueSaben) {

		trabajo.asignarRevisores(estosSonLosQueSaben.subList(0, 3));
	}

	private List<Usuario> agregarLosQueFaltan(List<Usuario> estosSaben) {


		int cantRevisores = estosSaben.size();

		List<Usuario> localRevisores = new ArrayList<Usuario>();

		localRevisores.addAll(this.revisores);

		localRevisores.removeAll(estosSaben);

		for (int i = cantRevisores; i < 3; i++) {

			Usuario rev = localRevisores.remove(0);
			estosSaben.add(rev);
		}

		return estosSaben;
	}

}